<template>
  <div class="bar">
    <div class="bar-item icon-list">
      <el-tooltip
        class="item"
        effect="dark"
        content="初始化"
        placement="bottom"
      >
        <el-button
          name="init"
          class=""
          size="small"
          icon="el-icon-document-add"
          @click="handleClick"
        />
      </el-tooltip>
      <!-- <el-tooltip
        class="item"
        effect="dark"
        content="清除 (Cmd + D)"
        placement="bottom"
      >
        <el-button
          name="delete"
          class="el-icon-delete"
          size="small"
          icon="delete"
          @click="handleClick"
        >
        </el-button>
      </el-tooltip> -->
      <el-tooltip
        class="item"
        effect="dark"
        content="撤销 (Cmd + Z)"
        placement="bottom"
      >
        <el-button
          :disabled="!isCanUse.canUndo"
          name="undo"
          class="el-icon-refresh-left"
          size="small"
          icon="undo"
          @click="handleClick"
        />
      </el-tooltip>

      <el-tooltip
        class="item"
        effect="dark"
        content="重做 (Cmd + Shift + Z)"
        placement="bottom"
      >
        <el-button
          :disabled="!isCanUse.canRedo"
          name="redo"
          class="el-icon-refresh-right"
          size="small"
          icon="redo"
          @click="handleClick"
        />
      </el-tooltip>

      <el-tooltip
        class="item"
        effect="dark"
        content="复制 (Cmd + C)"
        placement="bottom"
      >
        <el-button
          :disabled="!isCanUse.canCopy"
          name="copy"
          class="el-icon-document-copy"
          size="small"
          icon="copy"
          @click="handleClick"
        />
      </el-tooltip>

      <el-tooltip
        class="item"
        effect="dark"
        content="剪切 (Cmd + X)"
        placement="bottom"
      >
        <el-button
          :disabled="!isCanUse.canCut"
          name="cut"
          class="el-icon-scissors"
          size="small"
          icon="scissor"
          @click="handleClick"
        />
      </el-tooltip>

      <el-tooltip
        class="item"
        effect="dark"
        content="粘贴 (Cmd + V)"
        placement="bottom"
      >
        <el-button
          :disabled="!isCanUse.canPaste"
          name="paste"
          class="el-icon-copy-document"
          size="small"
          @click="handleClick"
        />
      </el-tooltip>

      <!-- <el-tooltip
        class="item"
        effect="dark"
        content="保存PNG (Cmd + S)"
        placement="bottom"
      >
        <el-button
          name="savePNG"
          class="el-icon-download"
          size="small"
          icon="download"
          @click="handleClick"
        />
      </el-tooltip> -->

      <!-- <el-tooltip
        class="item"
        effect="dark"
        content="打印 (Cmd + P)"
        placement="bottom"
      >
        <el-button
          name="print"
          class="el-icon-printer"
          size="small"
          @click="handleClick"
        />
      </el-tooltip> -->
      <el-tooltip
        class="item"
        effect="dark"
        content="执行"
        placement="bottom"
      >
        <el-button
          name="startFn"
          class="el-icon-video-play"
          size="small"
          @click="startFn"
        />
        <!-- <i class="el-icon-video-play" @click="startFn()" /> -->
      </el-tooltip>
    </div>
    <div class="bar-item btn-list">
      <el-button
        type="primary"
        size="medium"
        plain
        @click="handleSave"
      >
        保 存
      </el-button>
    </div>
  </div>
</template>

<script>
import { DataUri } from '@antv/x6';
import BusFactory from 'vue-happy-bus';
import { generateTree } from '@/utils/index';
import { cloneDeep } from 'lodash';
import DagGraph from '../../graph';
import DataJson from '../../const/dagdata.json';
import DataNoposJson from '../../const/dagNopos.json';

let graph = null;
let nodesData = [];
const nodeStatusList = [
  [
    {
      id: '1',
      status: 'running',
    },
    {
      id: '2',
      status: 'default',
    },
    {
      id: '3',
      status: 'default',
    },
    {
      id: '4',
      status: 'default',
    },
  ],
  [
    {
      id: '1',
      status: 'success',
    },
    {
      id: '2',
      status: 'running',
    },
    {
      id: '3',
      status: 'default',
    },
    {
      id: '4',
      status: 'default',
    },
  ],
  [
    {
      id: '1',
      status: 'success',
    },
    {
      id: '2',
      status: 'success',
    },
    {
      id: '3',
      status: 'running',
    },
    {
      id: '4',
      status: 'running',
    },
  ],
  [
    {
      id: '1',
      status: 'success',
    },
    {
      id: '2',
      status: 'success',
    },
    {
      id: '3',
      status: 'success',
    },
    {
      id: '4',
      status: 'failed',
    },
  ],
];
export default {
  name: 'ToolBar',
  components: {},
  props: {
    currentSelect: {
      type: String,
      default: 'none',
    },
  },
  data() {
    return {
      isCanUse: {
        canUndo: '',
        canRedo: '',
        canCopy: '',
        canCut: '',
        canPaste: '',
      },
      timer: '',
      bus: BusFactory(this), // 使用BusFactory将this绑定之后，返回一个 bus，即可无需关心销毁的问题了
    };
  },
  watch: {
    currentSelect(val) {
      const bol = val !== 'none';
      this.isCanUse.canCopy = bol;
      this.isCanUse.canCut = bol;
      if (!bol) {
        this.isCanUse.canPaste = bol;
      }
    },
  },
  created() {
    this.bus.$on('startEventFn', () => {
      this.startFn();
    });
  },
  mounted() {
    setTimeout(() => {
      graph = DagGraph?.graph;
      this.initEvent();
    }, 200);
  },
  methods: {
    formatData() {
      console.log('DataNoposJson', DataNoposJson);
      const { nodes, edges } = DataNoposJson;
      const edgesArr = cloneDeep(edges);
      const tree = generateTree(edgesArr, edges[0].source);
      // console.log('tree', tree);
      nodesData = null;
      nodesData = [];
      const nodesArr = cloneDeep(nodes);
      nodesData.push({ ...nodes[0], x: 400, y: 50 });
      // 遍历树，根据树来生成节点的 x，y 坐标：
      this.mapTree(tree, nodesArr, 1);
      const cells = nodesData.concat(edgesArr);
      return cells;
    },
    mapTree(treeDataArr, nodesArr, level = 1) {
      const nodes = cloneDeep(nodesArr);
      const treeData = cloneDeep(treeDataArr);
      treeData.forEach((item, index) => {
        if (level === 1) { // 根节点默认设置为 400,50
          const obj = nodes.find((i) => i.id === item.target);
          const pos = {
            x: 400,
            y: 50 * level + 90,
          };
          if (!nodesData.some((i) => i.id === obj.id)) {
            nodesData.push({ ...obj, ...pos });
          }
        } else if (treeData.length > 1 && level !== 1) {
          // 拿到上一级节点的x，y
          const { y } = nodesData.find((i) => i.id === item.source);
          const obj = nodes.find((i) => i.id === item.target);
          const pos = {
            x: 200 * (index + 1) + 100,
            // x: (720 * (index + 1)) / (treeData.length + 1) + x,
            y: 50 * level + y,
          };
          if (!nodesData.some((i) => i.id === obj.id)) {
            nodesData.push({ ...obj, ...pos });
          }
        } else if (treeData.length === 1 && level !== 1) {
          const { x, y } = nodesData.find((i) => i.id === item.source);
          const obj = nodes.find((i) => i.id === item.target);
          const pos = {
            x,
            y: 50 * level + y,
          };
          if (!nodesData.some((i) => i.id === obj.id)) {
            nodesData.push({ ...obj, ...pos });
          }
        }
        if (item.children && item.children.length > 0) {
          this.mapTree(item.children, nodes, level + 1);
        }
      });
    },
    startFn() {
      graph.clearCells();
      if (this.timer) {
        clearTimeout(this.timer);
        this.timer = null;
      }
      // this.init(DataJson);
      const data = this.formatData();
      this.init(data);
      this.showNodeStatus(Object.assign([], nodeStatusList));
      graph.centerContent();
    },
    // 初始化节点/边
    init(data = []) {
      const cells = [];
      data.forEach((item) => {
        if (item.shape === 'dag-edge') {
          cells.push(graph.createEdge(item));
        } else {
          // eslint-disable-next-line no-param-reassign
          delete item.component;
          cells.push(graph.createNode(item));
        }
      });
      graph.resetCells(cells);
    },
    async showNodeStatus(statusList) {
      const statusArr = statusList.shift();
      if (statusArr) {
        statusArr.forEach((item) => {
          const { id, status } = item;
          const node = graph.getCellById(id);
          const data = node.getData();
          node.setData({
            ...data,
            status,
          });
        });
      }
      this.timer = setTimeout(() => {
        this.showNodeStatus(statusList);
      }, 500);
    },
    initEvent() {
      const { history } = graph;
      history.on('change', () => {
        this.isCanUse.canUndo = history.canUndo();
        this.isCanUse.canRedo = history.canRedo();
      });
      graph.bindKey('ctrl+z', () => {
        if (history.canUndo()) {
          history.undo();
        }
        return false;
      });
      graph.bindKey('ctrl+shift+z', () => {
        if (history.canRedo()) {
          history.redo();
        }
        return false;
      });
      graph.bindKey('ctrl+d', () => {
        graph.clearCells();
        return false;
      });
      graph.bindKey('ctrl+s', () => {
        graph.toPNG((datauri) => {
          DataUri.downloadDataUri(datauri, 'chart.png');
        });
        return false;
      });
      graph.bindKey('ctrl+p', () => {
        graph.printPreview();
        return false;
      });
      graph.bindKey('ctrl+c', this.copy);
      graph.bindKey('ctrl+v', this.paste);
      graph.bindKey('ctrl+x', this.cut);
      // 连接桩事件
      // eslint-disable-next-line consistent-return
      graph.on('edge:connected', ({ edge }) => {
        const source = graph.getCellById(edge.source.cell);
        const target = graph.getCellById(edge.target.cell);
        console.log('connected source', source);
        console.log('connected target', target);
        console.log('connected edge', edge);
        // 只允许输入
        if (target.data.type === 'output') {
          return graph.removeEdge(edge.id);
        }

        // 只允许输出
        if (source.data.type === 'onlyIn') {
          return graph.removeEdge(edge.id);
        }

        // 如果线源头的一端链接桩只允许输入
        if (/in/.test(edge.source.port)) {
          return graph.removeEdge(edge.id);
        }

        // 目标一端链接桩只允许输出
        if (/out/.test(edge.target.port)) {
          return graph.removeEdge(edge.id);
        }

        if (source.data.type === 'condition') {
          console.log(source);
          console.log(target);
          console.log(edge);
          if (target.data.t === edge.id || target.data.f === edge.id) {
            return graph.removeEdge(edge.id);
          }
          this.$refs.dialogCondition.visible = true;
          this.$refs.dialogCondition.init(source.data, edge);
        }

        edge.attr({
          line: {
            strokeDasharray: '',
          },
        });
      });

      graph.on('node:change:data', ({ node }) => {
        const edges = graph.getIncomingEdges(node);
        const { status } = node.getData();
        if (edges) {
          edges.forEach((edge) => {
            if (status === 'running') {
              edge.attr('line/strokeDasharray', 5);
              edge.attr('line/style/animation', 'running-line 30s infinite linear');
            } else {
              edge.attr('line/strokeDasharray', '');
              edge.attr('line/style/animation', '');
            }
          });
        }
      });
    },
    copy() {
      const cells = graph.getSelectedCells();
      if (cells.length) {
        graph.copy(cells);
        this.isCanUse.canPaste = true;
      }
      return false;
    },
    cut() {
      const cells = graph.getSelectedCells();
      if (cells.length) {
        graph.cut(cells);
        this.isCanUse.canPaste = true;
      }
      return false;
    },
    paste() {
      if (!graph.isClipboardEmpty()) {
        const cells = graph.paste({ offset: 32 });
        graph.cleanSelection();
        graph.select(cells);
      }
      return false;
    },
    handleClick(event) {
      const { name } = event.currentTarget;
      switch (name) {
        case 'init':
          this.initGraph();
          break;
        case 'undo':
          graph.history.undo();
          break;
        case 'redo':
          graph.history.redo();
          break;
        case 'delete':
          graph.clearCells();
          break;
        case 'savePNG':
          graph.toPNG(
            (dataUri) => {
              // 下载
              DataUri.downloadDataUri(dataUri, 'chartx.png');
            },
            {
              backgroundColor: 'white',
              padding: {
                top: 20,
                right: 30,
                bottom: 40,
                left: 50,
              },
              quality: 1,
            },
          );
          break;
        case 'print':
          graph.printPreview();
          break;
        case 'copy':
          this.copy();
          break;
        case 'cut':
          this.cut();
          break;
        case 'paste':
          this.paste();
          break;
        default:
          break;
      }
    },
    initGraph() {
      graph.clearCells();
      graph.center(); // 内容居中
      graph.zoomTo(1); // 缩放比例
      // this.init(this.formatData());
      this.init(DataJson);
      // const startNode = graph.createNode({
      //   shape: 'start',
      //   x: 100,
      //   y: 300,
      // });
      // graph.addNode(startNode);
    },
    handleBack() {
      this.$emit('backTo');
    },
    handleSave() {
      this.$emit('saveStrategy');
    },
  },
};
</script>

<style lang="scss" scoped>
@import "./index.scss";
</style>
